package cn.signalpha.modules.com.controller.api;

import cn.signalpha.common.annotation.FormRepeatCommitAnnotation;
import cn.signalpha.common.cache.ConfigCache;
import cn.signalpha.common.cache.ConfigKeys;
import cn.signalpha.common.constant.AppConstant;
import cn.signalpha.common.dto.ConfigDTO;
import cn.signalpha.common.utils.Arith;
import cn.signalpha.common.utils.Assert;
import cn.signalpha.common.utils.OrderUtil;
import cn.signalpha.core.boot.ctrl.BaseController;
import cn.signalpha.core.mp.support.Condition;
import cn.signalpha.core.mp.support.Query;
import cn.signalpha.core.tool.api.R;
import cn.signalpha.modules.com.dto.WalletDTO;
import cn.signalpha.modules.com.dto.WithdrawDTO;
import cn.signalpha.modules.com.entity.User;
import cn.signalpha.modules.com.entity.Withdraw;
import cn.signalpha.modules.com.entity.enums.WalletSourceEnum;
import cn.signalpha.modules.com.entity.enums.WalletTypeEnum;
import cn.signalpha.modules.com.service.UserService;
import cn.signalpha.modules.com.service.WithdrawService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.validation.Valid;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 控制器
 *
 * @author signalpha
 */
@RestController
@AllArgsConstructor
@RequestMapping(AppConstant.APPLICATION_USER_NAME + "/wap/withdraw")
@Api(value = "提现", tags = "提现")
public class ApiWithdrawController extends BaseController {

	private final UserService userService;
	private final WithdrawService withdrawService;

    @GetMapping("/list")
    @ApiOperation(value = "提现记录", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name="status", dataType = "string", value = "0申请中 2提现成功 3提现失败"),
    })
    public R<IPage<Withdraw>> list(@ApiIgnore @RequestParam Map<String, Object> params, Query query) {
		params.put("userId_equal", getUser().getUserId().toString());
		QueryWrapper<Withdraw> queryWrapper = Condition.getQueryWrapper(params, Withdraw.class);
        return R.data(withdrawService.page(Condition.getPage(query), queryWrapper.lambda().orderByDesc(Withdraw::getId)));
    }

	@GetMapping("/info")
	@ApiOperation(value = "详情", notes = "传入id")
	public R<Withdraw> info(@RequestParam Long id) {
		return R.data(withdrawService.getById(id));
	}

	@GetMapping("/new")
	@ApiOperation(value = "最新提现记录", notes = "")
	public R<Withdraw> withdrawNew() {
		return R.data(withdrawService.getOne(Wrappers.<Withdraw>lambdaQuery().eq(Withdraw::getUserId, getUser().getUserId()).orderByDesc(Withdraw::getId).last("limit 1")));
	}

	@GetMapping("/sub")
	@ApiOperation(value = "计算提现服务费", notes = "传入提现金额")
	public R info(@RequestParam Double amount) {
		ConfigDTO.WithdrawDTO withdrawConfig = ConfigCache.getObject(ConfigKeys.WITHDRAW, ConfigDTO.WithdrawDTO.class);
		double subAmount = 0;
		if(withdrawConfig.getSubRatio() > 0){
			subAmount = Arith.mul(amount, Arith.div(withdrawConfig.getSubRatio(), 100d));
		}
		Map<String, Object> map = new LinkedHashMap<>();
		map.put("amount", Arith.sub(amount, subAmount));
		map.put("amountTotal", amount);
		map.put("subAmount", subAmount);
		return R.data(map);
	}

	@PostMapping("/save")
	@FormRepeatCommitAnnotation
	@ApiOperation(value = "提现申请", notes = "")
	@Transactional(rollbackFor = Exception.class)
	public R save(@Valid @RequestBody WithdrawDTO withdrawDTO) {
		ConfigDTO.WithdrawDTO withdrawConfig = ConfigCache.getObject(ConfigKeys.WITHDRAW, ConfigDTO.WithdrawDTO.class);
		Assert.isTrue(withdrawConfig.getOnOff() == 1, "提现暂未开放");
		Assert.isTrue(withdrawDTO.getAmount() >= withdrawConfig.getMin(), "最低提现金额为" + withdrawConfig.getMin());
		Assert.isTrue(withdrawDTO.getAmount() <= withdrawConfig.getMax(), "最大提现金额为" + withdrawConfig.getMax());

		User user = userService.getById(getUser().getUserId());
		if(withdrawDTO.getAmount() > user.getMoney()){
			return R.fail("您的提现额度为" + user.getMoney());
		}

		double subAmount = 0;
		double amountTotal = withdrawDTO.getAmount();
		if(withdrawConfig.getSubRatio() > 0){
			subAmount = Arith.mul(amountTotal, Arith.div(withdrawConfig.getSubRatio(), 100d));
		}
		double amount = Arith.sub(amountTotal, subAmount);
		Withdraw withdraw = new Withdraw();
		withdraw.setCategory(1);
		withdraw.setUserId(user.getId());
		withdraw.setOrderNo(OrderUtil.getOrderNo(""));
		withdraw.setType(withdrawDTO.getType());
		withdraw.setStatus(0);
		withdraw.setAmount(amount);
		withdraw.setTotalAmount(amountTotal);
		withdraw.setSubAmount(subAmount);
		withdraw.setBank(withdrawDTO.getBank());
		withdraw.setRealName(withdrawDTO.getRealName());
		withdraw.setAccount(withdrawDTO.getAccount());
		withdraw.setCreateTime(new Date());
		withdraw.setUpdateTime(withdraw.getCreateTime());
		withdrawService.save(withdraw);

		userService.updateUserMoney(WalletDTO.builder()
			.userId(user.getId())
			.amount(withdrawDTO.getAmount())
			.type(WalletTypeEnum.SUB.getType())
			.sourceId(withdraw.getId().toString())
			.sourceType(WalletSourceEnum.WITHDRAW_APPLY.getType())
			.remark(WalletSourceEnum.WITHDRAW_APPLY.getName())
			.build());
		return R.success("申请已提交，请耐心等待审核");
	}

}
